#ifndef RTSPCODECTHREAD_H
#define RTSPCODECTHREAD_H

#include <QObject>
#include <QtGui>
#include <QtNetwork>
#include <QThread>
#include <QtWidgets>

//必须加以下内容,否则编译不能通过,为了兼容C和C99标准
#ifndef INT64_C
#define INT64_C
#define UINT64_C
#endif
//引入ffmpeg头文件
extern "C" {
#include "libavutil/opt.h"
#include "libavutil/time.h"
#include "libavutil/frame.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avassert.h"
#include "libavutil/imgutils.h"
#include "libavutil/ffversion.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
#ifndef gcc45
#include "libavutil/hwcontext.h"
#include "libavutil/hwcontext_qsv.h"
#endif
}

typedef struct DecodeContext
{
    AVBufferRef *hw_device_ref;
}DecodeContext;

class RtspCodecThread : public QThread
{
    Q_OBJECT
public:
    explicit RtspCodecThread(QObject *parent = 0);
    static void initlib();
protected:
    void run();
private:
    volatile bool stopped;                          //线程停止标志位
    volatile bool isPlay;                           //播放视频标志位
    volatile bool isPause;                          //暂停播放标志位
    volatile bool isRtsp;                           //是否是视频流

    QMutex mutex;                                   //锁对象
    QDateTime lastTime;                             //最后的消息时间
    int frameCount;                                 //帧数统计
    int frameFinish;                                //一帧完成
    int videoWidth;                                 //视频宽度
    int videoHeight;                                //视频高度
    int oldWidth;                                   //上一次视频宽度
    int oldHeight;                                  //上一次视频高度
    int videoStreamIndex;                           //视频流索引
    int audioStreamIndex;                           //音频流索引
    int videoFps;                                   //视频流帧率

    int interval;                                   //采集间隔
    int sleepTime;                                  //休眠时间
    int checkTime;                                  //检测超时时间
    bool checkConn;                                 //检测视频流连接
    QString url;                                    //视频流地址
    QString hardware;                               //硬解码解码器类型

    bool saveFile;                                  //是否保存文件
    int saveInterval;                               //保存文件间隔,单位秒钟
    QString savePath;                               //保存文件夹
    QString fileName;                               //保存文件名称
    QTimer *timerSave;                              //定时器隔段时间存储文件
    QFile fileVideo;                                //保存视频文件
    QFile fileAudio;                                //保存音频文件

    uint8_t *buffer;                                //存储解码后图片buffer
    AVPacket *avPacket;                             //包对象
    AVFrame *avFrame;                               //帧对象
    AVFrame *avFrame2;                              //帧对象
    AVFrame *avFrame3;                              //帧对象
    AVFormatContext *avFormatContext;               //格式对象
    AVCodecContext *videoCodec;                     //视频解码器
    AVCodecContext *audioCodec;                     //音频解码器
    SwsContext *swsContext;                         //处理图片数据对象
    DecodeContext decode;                           //qsv解码所用结构体
    char *dtsData;
    const AVBitStreamFilter *filter;
    int av_bsf_filter(const AVBitStreamFilter *filter, AVPacket *pPacket, const AVCodecParameters *src);
    int decode_packet(AVCodecContext *avctx, AVPacket *packet);
private slots:
    void startSave();
    void stopSave();
    void save();
public:
    QDateTime getLastTime();                        //获取最后的活动时间
    QString getUrl();                               //获取url地址
    int getVideoWidth();                            //获取视频宽度
    int getVideoHeight();                           //获取视频高度
signals:
    void receivePlayOk();                           //播放成功
    void receivePlayError();                        //播放失败
    void receivePlayFinsh();                        //播放结束
    void receiveImage(const QImage &image);         //收到图片信号
    void sig_startSave();                           //启动和停止存储定时器
    void sig_stopSave();
public slots:
    void setInterval(int interval);                 //设置显示间隔
    void setSleepTime(int sleepTime);               //设置休眠时间
    void setCheckTime(int checkTime);               //设置检测连接超时
    void setCheckConn(bool checkConn);              //设置是否检测连接
    void setUrl(const QString &url);                //设置视频流地址
    void setHardware(const QString &hardware);      //设置硬件解码器名称
    void setSaveFile(bool saveFile);                //设置是否保存文件
    void setSaveInterval(int saveInterval);         //设置保存间隔
    void setSavePath(const QString &savePath);      //设置保存路径
    void setFileName(const QString &fileName);      //设置保存文件名称
    bool checkUrl();                                //校验url
    bool init();                                    //初始化视频对象
    void free();                                    //释放对象
    void play();                                    //播放视频对象
    void pause();                                   //暂停播放
    void next();                                    //停止采集线程
    void stop();                                    //停止采集线程
};

#endif // RTSPCODECTHREAD_H
